// import { saveDocument } from '@/services/ant-design-pro/documents';
import ROBOT_AVATAR from '@/assets/image/avatar_robo.png';
import PINGFEN from '@/assets/image/pingfen.png';
import { feedbacksStar } from '@/services/ant-design-pro/conversation';
import {
  DislikeOutlined,
  EditOutlined,
  FileSyncOutlined,
  HighlightOutlined,
  LikeOutlined,
} from '@ant-design/icons';
import { CheckOutlined } from '@ant-design/icons/lib';
import { Button, InputNumber, message, Tooltip } from 'antd';
import CanvasHighlighter from 'canvas-highlighter';
import DOMPurify from 'dompurify';
import React, { useEffect, useRef, useState } from 'react';
import { connect } from 'umi';
import EditCom from '../editCom';
import './index.less';
const versionsIcon =
  '<svg t="1693660245839" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4969" width="16" height="16"><path d="M877.35808 696.4992a23.04 23.04 0 0 1 22.38464-40.27904l29.44 16.36352c37.7856 20.992 50.0992 67.28704 26.49088 102.58432a76.42624 76.42624 0 0 1-26.48576 24.2176l-378.33728 210.23744c-24.7296 13.7472-55.5264 13.7472-80.256 0L92.25728 799.3856c-37.7856-20.992-50.09408-67.28704-26.48576-102.58432a76.42624 76.42624 0 0 1 26.48576-24.21248l29.83424-16.57856a23.04 23.04 0 0 1 22.37952 40.27904l-29.82912 16.57856a30.38208 30.38208 0 0 0-10.56768 9.55392c-8.35072 12.48768-4.08064 28.54912 10.56768 36.68992l378.33216 210.24256c10.81344 6.00576 24.6784 6.00576 35.49184 0l378.33728-210.24256a30.38208 30.38208 0 0 0 10.56768-9.55904c8.35072-12.48768 4.08064-28.54912-10.56768-36.6848l-29.44512-16.36352z m-2.432-219.21792a23.04 23.04 0 0 1 22.37952-40.27904l31.88224 17.7152c37.78048 20.992 50.09408 67.28704 26.48576 102.58432a76.42624 76.42624 0 0 1-26.48576 24.2176l-378.33728 210.23744c-24.7296 13.74208-55.5264 13.74208-80.256 0l-378.33728-210.24256c-37.7856-20.992-50.09408-67.28704-26.48576-102.58432a76.42624 76.42624 0 0 1 26.48576-24.2176l31.98976-17.77152a23.04 23.04 0 1 1 22.38464 40.27904l-31.98976 17.77664a30.38208 30.38208 0 0 0-10.56768 9.55392c-8.35072 12.48768-4.08064 28.54912 10.56768 36.6848l378.33216 210.24256c10.81344 6.01088 24.6784 6.01088 35.49184 0l378.33728-210.24256a30.38208 30.38208 0 0 0 10.56768-9.55392c8.35072-12.48768 4.08064-28.54912-10.56768-36.6848l-31.87712-17.7152z m-350.52544-415.18592a28.16 28.16 0 0 0-27.35616 0L117.32992 273.1008a28.16 28.16 0 0 0 0 49.2288l379.71456 211.01056a28.16 28.16 0 0 0 27.35616 0l379.71456-211.01056a28.16 28.16 0 0 0 0-49.2288l-379.71456-211.00544z m402.0992 170.7264c35.84 19.9168 48.7424 65.11616 28.83072 100.95616a74.24 74.24 0 0 1-28.83072 28.83072l-379.71456 211.01056a74.24 74.24 0 0 1-72.12544 0L94.94528 362.60864c-35.84-19.9168-48.74752-65.11616-28.83072-100.95104a74.24 74.24 0 0 1 28.8256-28.83584L474.66496 21.81632a74.24 74.24 0 0 1 72.12544 0l379.71456 211.00544z" fill="#000000" p-id="4970"></path></svg>';
const WriteCom: React.FC<any> = (props: any) => {
  const {
    curDoc,
    curFeedbacks,
    curOperationType,
    selVersionNo,
    documentUUID,
    user_score,
    standard_score,
  } = props.highClassWrite;
  const scoreInfo = useRef<any>({
    scoreValue: '',
    scoreShow: false,
    scoreLoading: false,
    scoreEdit: false,
  });
  const [isOneShowScore, setIsOneShowScore] = useState<boolean>(true); //是否是第一次展示 用于规避进入页面就执行动画
  const isInitHtml = useRef<any>(false); //文档内容是否初始化
  const [articleHTML, setArticleHTML] = useState<any>(null); //文档内容 从后台获取的数据
  const articleContentWrapRef = useRef<any>(null); //文档外层容器 用于滚动条
  const containerRef = useRef<any>(null); //文档容器
  const currentRangeRef = useRef<any>({}); //当前选中的range
  const isShowCancleBtn = useRef<any>(false); //是否显示取消评价按钮
  const highlighterRef = useRef<any>(null); //高亮实例
  const [editMode, setEditMode] = useState<boolean>(false); //评分loading
  interface operateStyleType {
    top: string; //位置 top
    left: string; //位置 left
    display: string; // 是否显示
  }

  //点赞modal样式
  const [operateStyle, setOperateStyle] = useState<operateStyleType>({
    top: '0',
    left: '0',
    display: 'none',
  });

  //公共更新model的方法
  const updateState = (updateObj: any) => {
    props.dispatch({
      type: 'highClassWrite/updateState',
      payload: updateObj,
    });
  };

  //高亮插件选中样式 type 1是赞 2是踩 isSubmit 是否提交过 初始选中和提交后的样式不一样
  const configStyle = (type = 1, isSubmit = false) => {
    let lineColor = type === 1 ? 'rgba(22, 214, 130, 1)' : 'rgba(250, 131, 131, 1)'; //下划线的颜色 用于 提交后的样式
    let fillColor = type === 1 ? 'rgba(96, 217, 164, 0.2)' : 'rgba(245, 112, 112, 0.2)'; //背景色

    let fillShow = isSubmit ? false : true; //是否显示背景色
    let lineShow = isSubmit ? true : false; //是否显示下划线

    let config = {
      rect: {
        fill: fillColor,
        visible: fillShow,
      },
      line: {
        stroke: lineColor,
        strokeWidth: 1,
        visible: lineShow,
      },
    };
    return config;
  };
  //鼠标选中
  const handleMouseUp = () => {
    const range = highlighterRef.current.getSelectionRange();
    // console.log(range);

    //选中范围
    if (range) {
      let end = highlighterRef.current?.getSelectionPosition()?.end; //选中文本的结束位置
      if (end < 0) {
        end = 0;
      }
      let selectionRange = highlighterRef.current.getSelectionRange(); //选中范围
      //获取containerRef距离页面左上角的距离 x = left ; y = top
      const containerOffset = containerRef.current?.getBoundingClientRect();

      //点赞modal位置 因为end返回的位置是距离页面左上角的距离 所以要减去containerRef距离页面左上角的距离
      let left = end?.left - containerOffset?.x;
      let top = end?.top - containerOffset?.y + 20;
      //在一行的最后一个字位置会偏移 重新计算
      if (left === 0) {
        left = containerOffset.width - 5;
        top = top - 26;
      }
      let position = {
        top: top + 'px',
        left: left + 'px',
      };

      isShowCancleBtn.current = false; //不显示取消评价按钮
      //显示点赞modal
      setOperateStyle({
        ...position,
        display: 'block',
      });
      currentRangeRef.current = {
        ...selectionRange,
        position,
      };
    } else {
      //隐藏点赞modal 防止点击其他地方也会显示点赞modal
      setOperateStyle({
        top: '0px',
        left: '0px',
        display: 'none',
      });
    }
  };
  //鼠标点击
  const handleDocumentClick = (event: any) => {
    // 通过传入点击位置获取 range id
    const id = highlighterRef.current.getRangeIdByPointer(event.pageX, event.pageY);
    if (id) {
      // //通过id获取range信息
      // const range = highlighterRef.current.getRange(id);
      // isShowCancleBtn.current = !range.isSave; //isSave表示是否已发送过的评价 已发送过的评价不取消
      // let position = range?.position;
      // // 显示点赞modal
      // setOperateStyle({
      //   ...position,
      //   display: 'block',
      // });
      // currentRangeRef.current = range; //当前选中的range
      // //如果没有发送过的 点击的时候 更新输入框操作状态
      // if (!range.isSave) {
      //   //更新操作
      //   updateState({
      //     curOperationType: { type: range.type === 1 ? 'zan' : 'cai', data: range },
      //   });
      // }
    }
    //当在选中文本后 不点赞 直接点击当前选中的文本 有可能会造成点赞modal仍留在页面上 延迟后计算一次
    setTimeout(() => {
      if (!id && !highlighterRef.current.getSelectionRange()) {
        setOperateStyle({
          top: '0px',
          left: '0px',
          display: 'none',
        });
      }
    }, 100);
  };
  //仿写 重写
  const fangaixie = (type: number) => {
    const range = currentRangeRef.current; //当前选中的range
    //更新操作
    updateState({
      curOperationType: { type: type === 1 ? 'fanxie' : 'gaixie', data: range },
    });
  };
  //将选中的文本添加到赞和踩列表中
  const addLickData = (type: number) => {
    const range = currentRangeRef.current; //当前选中的range
    range.version_no = selVersionNo; //选中的版本号
    //isSave是已经发送过的
    if (range.isSave) {
      range.config = configStyle(type, false);
      range.type = type; //1是赞 2是踩
    } else {
      const list = curFeedbacks.feedback_items || [];
      // 列表里是否已存在
      let isHas = list.find((item: any) => item.id === range?.id);
      //不存在 添加到curFeedbacks.feedback_items里和实例里
      if (!isHas) {
        range.config = configStyle(type, false);
        range.type = type; //1是赞 2是踩
        list.push(range);
        curFeedbacks.feedback_items = list;
        updateState({
          curFeedbacks: curFeedbacks,
        });
        highlighterRef.current?.addRange(range); //将选中的文本添加到高亮实例中
      } else {
        //存在 判断与之前类型是否一致 不一致梗概
        if (type !== isHas.type) {
          //更新curFeedbacks.feedback_items里的数据
          curFeedbacks.feedback_items = list.map((item: any) => {
            if (item.id === range?.id) {
              item.config = configStyle(type, false);
              item.type = type; //1是赞 2是踩
            }
            return item;
          });
          updateState({
            curFeedbacks: curFeedbacks,
          });
          highlighterRef.current?.updateRange(range); //将选中的文本更新到高亮实例中
        }
      }
      //更新操作
      updateState({
        curOperationType: { type: type === 1 ? 'zan' : 'cai', data: range },
      });
    }
  };
  //取消评价
  const cancleModal = (cancleRange: any) => {
    const range = cancleRange ? cancleRange : currentRangeRef.current; //当前选中的range
    highlighterRef.current?.deleteRange(range.id); //删除选中的文本
    //隐藏点赞modal
    setOperateStyle({
      top: '0px',
      left: '0px',
      display: 'none',
    });
    updateState({
      curOperationType: { type: 'input', data: null },
    });
  };
  //回显评分数据
  const loadFeedbacks = () => {
    try {
      if (curFeedbacks.feedback_items) {
        highlighterRef.current.clear();
        let feedback_items = curFeedbacks.feedback_items || []; //已点赞的数据 回显
        //过滤feedback_items里 start position end = null的数据
        feedback_items = feedback_items.filter(
          (item: any) => item.start !== null && item.end !== null,
        );
        //对数据进行处理 点赞和点踩 添加不同的样式
        let list = feedback_items.map((item: any) => {
          item.type = item.feedback_type;
          item.config = configStyle(item.feedback_type, true);
          item.isSave = true;
          return item;
        });
        setTimeout(() => {
          highlighterRef.current.renderRanges(list);
        }, 100);
        if (user_score !== 0) {
          // updateState({
          //   curOperationType:{ type: 'score', data:feedbacks?.star }
          // })
        }
      } else {
        highlighterRef.current.clear();
      }

      //已评分的情况下 默认不展开评分框 切换时使用展开状态不变
      if (user_score > 0) {
        scoreInfo.current = {
          ...scoreInfo.current,
          scoreValue: user_score || '',
          scoreLoading: false,
          scoreEdit: false,
        };
      } else {
        scoreInfo.current = {
          ...scoreInfo.current,
          scoreValue: user_score || '',
          scoreShow: true,
          scoreLoading: false,
          scoreEdit: true,
        };
        setIsOneShowScore(false); //展开评论框
      }
    } catch (error) {
      console.log(error);
    }
  };

  //初始化文章内容
  useEffect(() => {
    if (curDoc && curFeedbacks) {
      //渲染文档内容 将\n转换成p标签包裹
      let htmlCon = curDoc.content
        .split('\n')
        .map((p: any) => `<p>${p}</p>`)
        .join('');
      let sanitizeHtml = DOMPurify.sanitize(htmlCon); //使用DOMPurify.sanitize()方法过滤HTML字符串 防止XSS攻击
      setArticleHTML(sanitizeHtml); //渲染文档内容
      isInitHtml.current = true; //文档内容已初始化
      if (!highlighterRef.current) {
        highlighterRef.current = new CanvasHighlighter(containerRef.current);
        containerRef?.current?.addEventListener('mouseup', handleMouseUp);
        document.addEventListener('click', handleDocumentClick);
      }
      loadFeedbacks(); //回显反馈评分数据
      //切换文章时 滚动条回滚到顶部
      if (articleContentWrapRef?.current) {
        articleContentWrapRef.current.scrollTop = 0;
      }
    } else {
      if (highlighterRef.current) {
        highlighterRef.current = null;
        containerRef?.current?.removeEventListener('mouseup', handleMouseUp);
        document.removeEventListener('click', handleDocumentClick);
      }
      isInitHtml.current = false;
      setArticleHTML('');
      setOperateStyle({ top: '0px', left: '0px', display: 'none' });
    }
  }, [curDoc, curFeedbacks]);

  //点击星星评分
  const saveRate = async () => {
    const { scoreValue, scoreLoading } = scoreInfo.current;
    const scorePattern = /^(?:[1-9](?:\.\d)?|10(\.0)?)$/; // 正则表达式，匹配1-10的正整数
    if (scoreLoading) {
      message.open({
        type: 'info',
        content: '正在保存您的评分，请稍候！',
      });
      return;
    }
    if (!scoreValue) {
      message.open({
        type: 'info',
        content: '评分不能为空',
      });
      return;
    } else if (!scorePattern.test(Number(scoreValue))) {
      message.open({
        type: 'info',
        content: '请输入1-10的整数',
      });
      return;
    }
    scoreInfo.current.scoreLoading = true;
    const res = await feedbacksStar({
      document_uuid: documentUUID,
      user_score: scoreValue,
    });
    if (res.code === 0) {
      updateState({
        curOperationType: { type: 'score', data: scoreValue },
      });
      scoreInfo.current = {
        ...scoreInfo.current,
        scoreLoading: false,
        scoreShow: true,
        scoreEdit: false,
      };
    } else {
      scoreInfo.current.scoreLoading = false;
    }
  };

  useEffect(() => {
    //监听operationType 如果从用户输入组件那里传入取消点赞 则执行cancleModal方法
    if (curOperationType && curOperationType.type === 'cancelZanCai') {
      cancleModal(curOperationType?.data?.data);
    }
    //右侧输入框发送完赞和踩 要更新赞和踩的选中样式
    if (curOperationType && curOperationType.type === 'updateZanCai') {
      const { data } = curOperationType;
      data.config = configStyle(data.type, true);
      //更新选中样式
      highlighterRef.current?.updateRange(data);
      updateState({
        curOperationType: { type: 'input', data: null },
      });
    }
    //定位到原文
    if (curOperationType && curOperationType.type === 'showLocation') {
      const data = curOperationType.data;
      data.config = {
        rect: {
          fill: 'rgba(57,123,255, 0.3)',
          visible: true,
        },
        line: {
          stroke: 'rgba(22, 214, 130, 1)',
          strokeWidth: 1,
          visible: false,
        },
      };
      // 更新选中样式
      highlighterRef.current?.updateRange(data);
      updateState({
        curOperationType: { type: 'input', data: null },
      });
    }
  }, [curOperationType]);
  const toggleEdit = () => {
    setEditMode(true);
  };
  //翻转切换回来后重新渲染一下 解决画词错位
  useEffect(() => {
    if (!editMode && highlighterRef.current) {
      setTimeout(() => {
        highlighterRef.current.clear();
        loadFeedbacks(); //回显反馈评分数据
      }, 200);
    }
  }, [editMode]);

  // 过滤非数字字符
  const changeScore = (value: any) => {
    // 格式化为带一位小数点的形式
    const formattedValue = value % 1 === 0 ? `${value}.0` : value;
    scoreInfo.current.scoreValue = formattedValue;
  };
  useEffect(() => {
    if (scoreInfo.current) {
      // console.log(scoreInfo.current);
    }
  }, [scoreInfo.current]);
  const toggleScoreShow = () => {
    setIsOneShowScore(false);
    scoreInfo.current.scoreShow = !scoreInfo.current.scoreShow;
  };

  //根据分数返回对应的颜色
  const getBgColor = (score: number) => {
    // 高分段：8.0-10.0 (包含8.0，10.0)  = bgcolor1
    // 中分段：6.0-8.0 (包含6.0，不包含8.0)  = bgcolor2
    // 低分段：6.0以下 (不包含6.0) =bgcolor3
    if (score >= 8 && score <= 10) {
      return 'bgcolor1';
    } else if (score >= 6 && score <= 8) {
      return 'bgcolor2';
    } else {
      return 'bgcolor3';
    }
  };
  return (
    <div className={`articleMainWrap ${scoreInfo.current.scoreShow ? 'maxMargin' : 'minnMargin'}`}>
      {!isOneShowScore && (
        <div
          className={`scoreDialog ${
            !scoreInfo.current.scoreShow ? 'scoreDialogHide' : 'scoreDialogShow'
          }`}
        >
          <div className="scoreList">
            <span className="scoreList-hd">AI评分</span>
            <div className="scoreList-bd ">{standard_score}</div>
          </div>
          <div className="scoreList">
            <span className="scoreList-hd">用户评分</span>
            {scoreInfo.current.scoreEdit ? (
              <div className="scoreList-bd inputScore">
                <div className="inputScore-hd">
                  <Tooltip
                    defaultOpen={false}
                    trigger={['hover']}
                    color="blue"
                    title="请输入1.0-10.0的评分"
                    placement="topLeft"
                    overlayClassName="numeric-input"
                  >
                    {/* <Input
                    type="text"
                    bordered={false}
                    placeholder="1-10分"
                    defaultValue={
                      scoreInfo.current.scoreValue <= 0 ? '' : scoreInfo.current.scoreValue
                    }
                    maxLength={2}
                    onChange={changeScore}
                  /> */}
                    <InputNumber
                      min={1}
                      placeholder="1-10分"
                      precision={1}
                      max={10}
                      defaultValue={
                        scoreInfo.current.scoreValue <= 0 ? '' : scoreInfo.current.scoreValue
                      }
                      onChange={changeScore}
                      style={{ width: '100%' }}
                    />
                  </Tooltip>
                </div>
                <div className="inputScore-bd">
                  <Button onClick={saveRate} shape="circle" size="small" icon={<CheckOutlined />} />
                </div>
              </div>
            ) : (
              <div className={`scoreList-bd ${getBgColor(scoreInfo.current.scoreValue)}`}>
                {scoreInfo.current.scoreValue}
              </div>
            )}
          </div>
        </div>
      )}

      <div className="articleMain">
        <div className={`${editMode ? 'domVisible' : 'domHidden'}`}>
          <EditCom
            setEditMode={setEditMode}
            getVersions={props.getVersions}
            setVersionNo={props.setVersionNo}
          ></EditCom>
        </div>
        {curDoc && (
          <div
            style={{
              height: 'calc(100% - 0px)',
            }}
            className={`curDocBox ${!editMode ? 'domVisible' : 'domHidden'}`}
          >
            <div className="score-box">
              {/* <span className="score-hd">全文评价：</span>
              <div className="score-bd">
                <Rate value={score} disabled={scoreLoad} onChange={(e) => changeRate(e)} />
              </div>
              <span className="score-ft">
                {desc[score - 1]} {scoreLoad && <SyncOutlined spin />}{' '}
              </span> */}
              <div className="docBtnWrap">
                <Tooltip title="编辑文章" color="cyan">
                  <Button shape="circle" onClick={toggleEdit} icon={<EditOutlined />} />
                </Tooltip>
                <Tooltip title="版本记录" color="orange" onClick={() => props.selectItem(3)}>
                  <Button
                    shape="circle"
                    icon={<div dangerouslySetInnerHTML={{ __html: versionsIcon }} />}
                  />
                </Tooltip>
                <Tooltip title="文章评分" color="blue">
                  {scoreInfo.current.scoreShow ? (
                    <div className="avatarBox" onClick={toggleScoreShow}>
                      <img className="avatar" src={ROBOT_AVATAR} height={39} width={39} />
                    </div>
                  ) : (
                    <div
                      className={`avatarBox ${scoreInfo.current.scoreValue > 0 ? '' : 'redDot'}`}
                      onClick={toggleScoreShow}
                    >
                      <img className="avatar" src={PINGFEN} height={39} width={39} />
                    </div>
                  )}
                </Tooltip>
              </div>
            </div>
            {/* <div className="articleTitle">{curDoc?.title}</div> */}
            <div className="articleContentWrap slideOverflow" ref={articleContentWrapRef}>
              <div className="articleContent" ref={containerRef}>
                {<div className="htmlBox" dangerouslySetInnerHTML={{ __html: articleHTML }}></div>}
              </div>
              <div className="operateModal" style={operateStyle}>
                <div className="operateList zanColor" onClick={() => addLickData(1)}>
                  <span className="operateList-hd">
                    <LikeOutlined />
                  </span>
                  <span className="operateList-bd">赞</span>
                </div>
                <div className="operateList caiColor" onClick={() => addLickData(2)}>
                  <span className="operateList-hd">
                    <DislikeOutlined />
                  </span>
                  <span className="operateList-bd">踩</span>
                </div>
                <div className="operateDividerLine"></div>
                <div className="operateList" onClick={() => fangaixie(1)}>
                  <span className="operateList-hd">
                    <HighlightOutlined />
                  </span>
                  <span className="operateList-bd">仿写</span>
                </div>
                <div className="operateList" onClick={() => fangaixie(2)}>
                  <span className="operateList-hd">
                    <FileSyncOutlined />
                  </span>
                  <span className="operateList-bd">重写</span>
                </div>
                {isShowCancleBtn.current && (
                  <div className="operateList" onClick={() => cancleModal(null)}>
                    取消
                  </div>
                )}
              </div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

// export default WriteCom;
export default connect(({ highClassWrite }) => ({ highClassWrite }))(WriteCom);
